#pragma once
#pragma warning( disable: 4251 ) 

#ifdef WGLENGINE_DLL
#define WGLENGINE_EXPORT __declspec(dllexport)
#else
#define WGLENGINE_EXPORT __declspec(dllimport)
#endif


#include <queue>
#include <stack>
#include <sstream>

enum InputType {MousePress = 0, MouseMove = 1, MouseRelease = 2, MouseWheel, KeyPress, KeyHold, KeyRelease};

class WGLENGINE_EXPORT Input
{
public:
	int key;
	InputType type;

	virtual std::string ToString() {
		std::stringstream ss;
		ss << key;
		ss << ", ";
		ss << type;
		return ss.str();
	}

};

class WGLENGINE_EXPORT MouseInput : public Input
{
public:
	int x;
	int y;
	float delta;

	std::string ToString() override {
		std::stringstream ss;
		ss << key << ", " << type << ", " << x << ", " << y << ", " << delta;
		return ss.str();
	}
};

class WGLENGINE_EXPORT InputListener
{
public:
	InputListener(){}
	~InputListener(){}

	void EnqueueInput(std::shared_ptr<Input> input) {
		inputQueue.push(input);
	}

	void DequeueInput() {
		inputQueue.pop();
	}

	bool HasFocus() {
		return hasFocus;
	}

	int InputQueueSize() {
		return (int) inputQueue.size();
	}

	std::shared_ptr<Input> Peek() {
		return inputQueue.front();
	}

	static std::stack<std::shared_ptr<InputListener>> inputStack;
	virtual void ProcessInputQueue() = 0;

private:
	bool hasFocus;
	std::queue<std::shared_ptr<Input>> inputQueue;
};